// This file is part of OpenMeca, an easy software to do mechanical simulation.
//
// Author(s)    :  - Damien ANDRE  <openmeca@gmail.com>
//
// Copyright (C) 2012 Damien ANDRE
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



#include <iostream>
#include <QMessageBox>

#include "OpenMeca/Core/UserItem.hpp"
#include "OpenMeca/Core/UserChildItem.hpp"
#include "OpenMeca/Core/System.hpp"


namespace OpenMeca
{
  namespace Core
  {


    void
    UserItem::UnselectAll()
    {
      SetOf<UserItem>& set = AutoRegister<UserItem>::GetGlobalSet();
      SetOf<UserItem>::it it;
      for (it=set.Begin() ; it != set.End(); it++ )
	(*it)->SetIsSelected(false);
    }



    UserItem::UserItem(const std::string strType,  QTreeWidgetItem& parent)
      :Item(strType),
       name_(strType),
       icon_(":/Icons/"+QString(strType.c_str())+".png"),
       mainTreeItem_(new Gui::MainTreeItem(parent, *this)),
       secondaryTreeItems_(),
       dependentItems_(),
       parentsItems_(),
       isSelected_(false)
    {
      name_ = System::Get().GetAutomaticName(strType);
    }


    UserItem::~UserItem()
    {
      dependentItems_.DeleteAllItem();
      delete mainTreeItem_;
    }

    void
    UserItem::MainTreeItemIsDeleted()
    {
      mainTreeItem_ = 0;
    }


    void 
    UserItem::AddChildItem(UserItem& item)
    {
      dependentItems_.AddItem(item); 
    }

    void 
    UserItem::EraseChildItem(UserItem& item)
    {
      dependentItems_.RemoveItem(item);
    }

    const SetOf<UserItem>& 
    UserItem::GetDependentItems() const
    {
      return dependentItems_;
    }


    SetOf<UserItem>& 
    UserItem::GetDependentItems()
    {
      return dependentItems_;
    }

    SetOfBase<UserItem> 
    UserItem::GetAllDependentItems()
    {
      SetOfBase<UserItem> allDependentItems;
      ConcatenateDependentItems(allDependentItems);
      return allDependentItems;
    }

    void 
    UserItem::ConcatenateDependentItems(SetOfBase<UserItem>& allDependentItems)
    {
      SetOf<UserItem>& set = dependentItems_;
      SetOf<UserItem>::it it;
      for (it=set.Begin() ; it != set.End(); it++ )
	{
	  if (allDependentItems.Contain(**it) == false)
	    {
	      allDependentItems.AddItem(**it);
	      (*it)->ConcatenateDependentItems(allDependentItems);
	    }
	}
    }





    const Gui::MainTreeItem& 
    UserItem::GetMainTreeItem() const
    {
      return *mainTreeItem_;
    }

    Gui::MainTreeItem& 
    UserItem::GetMainTreeItem()
    {
      return *mainTreeItem_;
    }

    const std::string&
    UserItem::GetName() const
    {
      return name_;
    }

    std::string&
    UserItem::GetName()
    {
      return name_;
    }

    QIcon&
    UserItem::GetIcon()
    {
      return icon_;
    }

    const QIcon&
    UserItem::GetIcon() const
    {
      return icon_;
    }

    void
    UserItem::Update()
    {
      GetMainTreeItem().setText(0, GetName().c_str());
      UpdateIcon();
      GetMainTreeItem().Update();
      Core::SetOf<UserItem>::it it;
      for (it = dependentItems_.Begin() ; it != dependentItems_.End(); it++ )
	{
	  (*it)->Update();
	}
    }
    
    void
    UserItem::ChangeParentTreeItem(QTreeWidgetItem& newparent)
    {
      QTreeWidgetItem*  myparent = GetMainTreeItem().parent();
      
      if (myparent != &newparent)
	{
	  delete mainTreeItem_;
	  mainTreeItem_ = new Gui::MainTreeItem(newparent, *this);
	}
    }
    
    void
    UserItem::Select()
    {
      isSelected_ = true;

      SetOfBase<UserItem> set = GetAssociatedSelectedItem();
      SetOfBase<UserItem>::it it;
      for (it=set.Begin() ; it != set.End(); it++ )
	(*it)->Select();

    }

    void
    UserItem::UnSelect()
    {
      isSelected_ = false;
      SetOfBase<UserItem> set = GetAssociatedSelectedItem();
      SetOfBase<UserItem>::it it;
      for (it=set.Begin() ; it != set.End(); it++ )
	(*it)->UnSelect();
    }


    void
    UserItem::SetIsSelected(bool val)
    {
      isSelected_ = val;
    }


    bool
    UserItem::IsSelected() const
    {
      return isSelected_;
    }

    SetOfBase<UserItem> 
    UserItem::GetAssociatedSelectedItem()
    {
      return SetOfBase<UserItem>();
    }



  
  }
}


